<script lang="ts" setup>
import type { VbenFormProps } from '@vben/common-ui';

import type { VxeGridListeners, VxeGridProps } from '#/adapter/vxe-table';
import type { DefApplicationModel } from '#/api';
import type { SopDocInfoModel } from '#/api/devOperation/sop/model/sopDocInfoModel';

import { onMounted, ref } from 'vue';
import { useRouter } from 'vue-router';

import { Page } from '@vben/common-ui';

import { useLoading } from '@vben-core/shadcn-ui';

import { Button, TabPane, Tabs } from 'ant-design-vue';

import { useVbenVxeGrid } from '#/adapter/vxe-table';
import { SopDocAppApi } from '#/api/devOperation/sop/sopDocApp';
import { SopDocInfoApi } from '#/api/devOperation/sop/sopDocInfo';
import { TableAction } from '#/components/table-action';
import { PermCode } from '#/enums/perm';
import { useMessage } from '#/hooks/web/useMessage';

import Form from './modules/form.vue';
import { gridSchemas, searchFormSchemas } from './schemas';

const hasTopTableDropDownActions = ref(false);
const { createMessage, createConfirm } = useMessage();
const [openFullLoading, closeFullLoading] = useLoading({
  // text: '加载中...',
});
const activeKey = ref<string>('');
const tabsData = ref<any[]>([]);
const formRef = ref();

const formOptions: VbenFormProps = {
  ...searchFormSchemas,
  collapsed: true,
};
const permCode = PermCode.devOperation.sop.sopDocInfo;

const gridOptions: VxeGridProps<DefApplicationModel.DefApplicationResultVO> = {
  ...gridSchemas,
  height: 'auto',
  keepSource: true,
  pagerConfig: {
    enabled: false,
  },
  treeConfig: {
    expandAll: true,
    iconOpen: 'vxe-icon-folder-open',
    iconClose: 'vxe-icon-folder',
    showLine: true,
    rowField: 'id',
    childrenField: 'children',
  },
  proxyConfig: {
    autoLoad: false,
    ajax: {
      query: async (_, formValues) => {
        if (!formValues.docAppId) {
          formValues.docAppId = activeKey.value;
        }
        const keyword = formValues.keyword;

        const list = await SopDocInfoApi.tree(formValues);
        if (!keyword) {
          return list;
        }

        return searchRow(keyword.toLowerCase(), list);
      },
    },
  },
};

const folderHandler = (row: SopDocInfoModel.SopDocInfoResultVO) => {
  return row.isFolder === 1;
};

const searchHandler = (
  searchText: string,
  row: SopDocInfoModel.SopDocInfoResultVO,
) => {
  return (
    (row.docName && row.docName.toLowerCase().includes(searchText)) ||
    (row.docTitle && row.docTitle.toLowerCase().includes(searchText))
  );
};

const searchRow = (
  search: string,
  rows: SopDocInfoModel.SopDocInfoResultVO[],
) => {
  const ret = [];
  for (const row of rows) {
    // 找到分类
    if (folderHandler(row)) {
      if (searchHandler(search, row)) {
        ret.push(row);
      } else {
        // 分类名字没找到，需要从子文档中找
        const children = row.children || [];
        const searchedChildren = searchRow(search, children);
        // 如果子文档中有
        if (searchedChildren && searchedChildren.length > 0) {
          const rowCopy = Object.assign({}, row);
          rowCopy.children = searchedChildren;
          ret.push(rowCopy);
        }
      }
    } else {
      // 不是分类且被找到
      if (searchHandler(search, row)) {
        ret.push(row);
      }
    }
  }
  return ret;
};

const activeTab = (id: string) => {
  activeKey.value = id;

  gridApi.reload({ docAppId: id });
};

const loadApp = async (appId: string) => {
  const list = await SopDocAppApi.query({});
  tabsData.value = list;

  const length = tabsData.value.length;
  if (length > 0) {
    let targetId;
    for (const id of tabsData.value) {
      if (id === appId) {
        targetId = id;
        break;
      }
    }
    if (!targetId) {
      targetId = tabsData.value[0].id;
    }
    activeKey.value = targetId;
    activeTab(targetId);
  }
};

onMounted(() => {
  loadApp('0');
});

const gridEvents: VxeGridListeners<any> = {
  checkboxChange() {
    const records = gridApi.grid?.getCheckboxRecords();
    hasTopTableDropDownActions.value = records.length > 0;
  },
  checkboxAll() {
    const records = gridApi.grid?.getCheckboxRecords();
    hasTopTableDropDownActions.value = records.length > 0;
  },
};

const [Grid, gridApi] = useVbenVxeGrid({
  gridEvents,
  formOptions,
  gridOptions,
});

// 同步
const handleSync = async (row: any, e: Event) => {
  e?.stopPropagation();
  openFullLoading();
  try {
    await SopDocInfoApi.syncDoc({ id: row.id });
    createMessage.success('同步成功');
  } finally {
    closeFullLoading();
  }
};
// 发布
const handleFolderPublish = async (row: any, e: Event) => {
  e?.stopPropagation();

  const result = await SopDocInfoApi.publish(row.id, 1);
  if (result) {
    createMessage.success('发布成功');
    gridApi.reload();
  } else {
    createMessage.error('发布失败');
  }
};

// 下线
const handleFolderOffline = async (row: any, e: Event) => {
  e?.stopPropagation();

  const result = await SopDocInfoApi.publish(row.id, 0);
  if (result) {
    createMessage.success('下线成功');
    gridApi.reload();
  } else {
    createMessage.error('下线失败');
  }
};

const handlePublishOrOffline = async (row: any, e: Event) => {
  e?.stopPropagation();

  const result = await SopDocInfoApi.publish(
    row.id,
    row.isPublish === 1 ? 0 : 1,
  );
  if (result) {
    createMessage.success('修改状态成功');
    gridApi.reload();
  } else {
    createMessage.error('修改状态失败');
  }
};

const { replace } = useRouter();
const handleViewDoc = () => {
  replace({ path: '/doc/api' });
};

// 打开新增表单
const handleSyncAppDoc = () => {
  createConfirm({
    iconType: 'warning',
    title: `提示`,
    content: `确定要同步远程接口吗?`,
    onOk: async () => {
      openFullLoading();
      try {
        const result = await SopDocInfoApi.syncAppDoc({ id: activeKey.value });
        if (result) {
          createMessage.success('同步成功');
          gridApi.reload();
        } else {
          createMessage.error('同步失败');
        }
      } finally {
        closeFullLoading();
      }
    },
  });
};

const handleClick = (key: number | string) => {
  activeTab(key as string);
};

function handleAddApp() {
  formRef.value.open();
}

function handleAddSuccess(appId: string) {
  loadApp(appId);
}
</script>

<template>
  <Page auto-content-height>
    <Tabs
      class="sop-app-tabs bg-card px-4"
      v-model:active-key="activeKey"
      @change="handleClick"
    >
      <TabPane :key="item.id" :tab="item.appName" v-for="item in tabsData" />
      <template #rightExtra>
        <Button
          type="primary"
          v-hasAnyPermission="[permCode.addApp]"
          @click="handleAddApp"
        >
          添加
        </Button>
      </template>
    </Tabs>
    <Form ref="formRef" @success="handleAddSuccess" />
    <Grid>
      <template #toolbar-buttons>
        <TableAction
          :actions="[
            {
              label: '同步全部接口',
              type: 'primary',
              auth: [permCode.sync],
              onClick: handleSyncAppDoc.bind(null),
            },
            {
              label: '查看文档',
              type: 'default',
              onClick: handleViewDoc.bind(null),
            },
          ]"
        />
      </template>
      <template #toolbar-tools></template>
      <template #ACTION="{ row }">
        <TableAction
          :actions="[
            {
              label: '发布',
              type: 'link',
              size: 'small',
              auth: [permCode.publish],
              ifShow: () => {
                return row.isFolder === 1;
              },
              popConfirm: {
                title: `确定要发布[${row.docTitle}]下所有接口吗？`,
                confirm: handleFolderPublish.bind(null, row),
              },
            },
            {
              label: '下线',
              type: 'link',
              auth: [permCode.offline],
              size: 'small',
              danger: true,
              ifShow: () => {
                return row.isFolder === 1;
              },
              popConfirm: {
                title: `确定要下线[${row.docTitle}]下所有接口吗？`,
                confirm: handleFolderOffline.bind(null, row),
              },
            },
            {
              label: row.isPublish ? '下线' : '发布',
              danger: row.isPublish === 1,
              auth: [permCode.publish, permCode.offline],
              type: 'link',
              size: 'small',
              ifShow: () => {
                return row.isFolder === 0;
              },
              popConfirm: {
                title: `确定要修改[${row.docTitle}]发布状态吗？`,
                confirm: handlePublishOrOffline.bind(null, row),
              },
            },
            {
              label: '同步',
              type: 'link',
              auth: [permCode.sync],
              size: 'small',
              popConfirm: {
                title: row.isFolder
                  ? `确定要同步[${row.docTitle}]下所有接口吗？`
                  : `确定要同步[${row.docTitle}]吗？`,
                confirm: handleSync.bind(null, row),
              },
            },
          ]"
        />
      </template>
    </Grid>
  </Page>
</template>
<style lang="scss" scoped>
:deep(.sop-app-tabs) {
  .ant-tabs-nav {
    margin: 0;
  }
}
</style>
